package com.mantou.mantouaiagent.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mantou.mantouaiagent.entities.User;
import com.mantou.mantouaiagent.entities.dto.UserDto;
import com.mantou.mantouaiagent.exp.BusinessException;
import com.mantou.mantouaiagent.mapper.UserMapper;
import com.mantou.mantouaiagent.resp.ResultData;
import com.mantou.mantouaiagent.resp.ReturnCodeEnum;
import com.mantou.mantouaiagent.service.UserService;
import com.mantou.mantouaiagent.util.IpUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @auther zzyy
 * @create 2024-10-03 19:48
 */
@RestController
public class UserController
{
    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private UserService userService;
    @Resource
    private RedisTemplate<String,String> stringRedisTemplate;
    @Value("${jwt.secret}")
    private String jwtSecret;
    @Resource //密码加盐处理
    private PasswordEncoder passwordEncoder;

    // 查询All
    @GetMapping("/user/list")
    public ResultData<List<User>> getList(){
        List<User> list = userService.list();
        return ResultData.success(list);
    }

    @GetMapping("/user/exist")
    public ResultData<User> getUserName(String username){
        User one = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if(!ObjectUtil.isEmpty(one)){
            User user = new User();
            user.setUsername(one.getUsername());
            return ResultData.success(user);
        }
        return ResultData.success(null);
    }


    @GetMapping(value = "/user/get/{id}")
    public ResultData<User> getUserById(@PathVariable("id") Integer id)
    {
        //这里模拟id等于负数会报错
        if(id < 1)
        {
            throw new BusinessException(ReturnCodeEnum.REQPARAM_NEGATIVE.getCode(),
                    ReturnCodeEnum.REQPARAM_NEGATIVE.getMessage());
        }
        return ResultData.success(userService.getById(id));
    }

    //============以下是AI开发相关==============================
    //============以下是AI开发相关==============================
    //============以下是AI开发相关==============================

    /** 2024.12.29
     * V2 register.html是form表单格式整个提交，取消@RequestBody
     *    springsecurity加盐加密处理
     * @param user
     * @return
     */
    @PostMapping(value = "/user/register")
    public ResultData add(@RequestBody User user){
        // 1.非空效验
        if(Objects.isNull(user))
        {
            throw new BusinessException(ReturnCodeEnum.REQPARAM_ISNULL.getCode(),
                    ReturnCodeEnum.REQPARAM_ISNULL.getMessage());
        }
        //2.校验用户名是否存在
        User data = getUserName(user.getUsername()).getData();
        if(!ObjectUtil.isEmpty(data)){
            return ResultData.fail(ReturnCodeEnum.USERNAME_EXIST.getCode(),
                    ReturnCodeEnum.USERNAME_EXIST.getMessage());
        }
        // 2.执行数据库的添加操作
        // 2.1 将密码进行加盐处理，存进数据库的就不再是明文裸密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        boolean result = userService.save(user);
        if(result)
        {
            return ResultData.success(result);
        }
        return ResultData.fail(ReturnCodeEnum.RC205.getCode(),ReturnCodeEnum.RC205.getMessage());
    }

    /**
     * V5 含有验证码+JWT+MySQL查询+springsecurity加盐加密处理+登录成功后给首页用户信息 2024.12.29
     * 对应login.html的V3版本呢
     * @param userDTO
     * @param request
     * @return
     */
    @PostMapping(value = "/user/login")
    public ResultData login(@Validated @RequestBody UserDto userDTO, HttpServletRequest request)
    {
        String ipAddress = IpUtil.getIpAddress(request);
        //1 验证码判断
        String captchaRedisKey = "captcha-" + SecureUtil.md5(ipAddress);
        String captchaValue = (String)stringRedisTemplate.opsForValue().get(captchaRedisKey);

        if(StrUtil.hasEmpty(captchaValue) || !userDTO.getCaptcha().equalsIgnoreCase(captchaValue) )
        {
            return ResultData.fail(ReturnCodeEnum.INVALID_CAPTCHA.getCode(),
                    ReturnCodeEnum.INVALID_CAPTCHA.getMessage());
        }
        //2 验证用户名和密码
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(User::getUsername,userDTO.getUsername());
        User user = userService.getOne(lambdaQueryWrapper);

        if(null != user && passwordEncoder.matches(userDTO.getPassword(), user.getPassword()))
        {
            //3 生成 JWT并返回给前端,认证通过后还需要向前端返回一个JSON格式的数据里面包括了JWT
            ConcurrentHashMap<String, Object> payLoad = new ConcurrentHashMap<>();
            payLoad.put("uid", user.getId());
            payLoad.put("username", user.getUsername());
            //4 生成 JWT+用户信息并返回给前端
            ConcurrentHashMap<String, String> result = new ConcurrentHashMap<>();
            result.put("jwt", JWTUtil.createToken(payLoad, jwtSecret.getBytes()));
            result.put("username", user.getUsername());

            return ResultData.success(result);
        }

        return ResultData.fail(ReturnCodeEnum.USERNAME_OR_PASSWORD_ERROR.getCode(),
                ReturnCodeEnum.USERNAME_OR_PASSWORD_ERROR.getMessage());
    }




    @GetMapping(value = "/user/test")
    public String test()
    {
        return "success is test";
    }



}
